package com.jiang.mapper;

import com.jiang.bean.Song;
import com.jiang.utils.LuceneUtils;
import com.jiang.utils.SongUtils;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.springframework.stereotype.Repository;

import java.io.IOException;
import java.io.StringReader;
import java.nio.file.FileSystems;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by dllo on 18/5/7.
 */
@Repository
public class LuceneDao {
    /**
     * 创建索引
     */
    public void addIndex(Song song) throws IOException {
        IndexWriter indexWriter = LuceneUtils.getIndexWriterOfSP();
        Document doc = SongUtils.songToDocument(song);
        indexWriter.addDocument(doc);
        indexWriter.forceMerge(10);
        indexWriter.close();
    }

    /**
     * 删除索引
     */
    public void delIndex(String filedName, String fieldValue) throws IOException {
        IndexWriter indexWriter = LuceneUtils.getIndexWriterOfSP();
        Term term = new Term(filedName, fieldValue);
        //根据字段删除索引
        indexWriter.deleteDocuments(term);
        indexWriter.close();
    }

    /**
     * 更新索引
     */
    public void updateIndex(String fieldName, String fieldValue, Song song) throws IOException {
        IndexWriter indexWriter = LuceneUtils.getIndexWriterOfSP();
        Term term = new Term(fieldName, fieldValue);
        Document document = SongUtils.songToDocument(song);
        //1.设置更新条件
        //2.设置更新内容对象
        indexWriter.updateDocument(term, document);
        indexWriter.close();
    }

    /**
     * 分页：每页10条
     */
    public List<Song> findIndex(String keywords, int start, int rows) throws Exception {
        Directory directory = FSDirectory.open(FileSystems.getDefault().getPath(LuceneUtils.INDEXURL_ALL));
        IndexSearcher indexSearcher = LuceneUtils.getIndexSearcherOfSP();

        //根据哪几个字段搜索...
        String fields[] = {"name", "author", "album"};

        //查询分析程序(查询解析)
        QueryParser queryParser = new MultiFieldQueryParser(fields, LuceneUtils.getAnalyzer());

        //不同规则构造不同的子类
        Query query = queryParser.parse(keywords);

        //这里索引的是索引目录，会把整个索引目录都读一遍
        //根据query查询，返回前N条
        TopDocs topDocs = indexSearcher.search(query, start + rows);

        System.out.println("总记录数=" + topDocs.totalHits);

        ScoreDoc scoreDoc[] = topDocs.scoreDocs;

        /**添加设置文字高亮begin*/
        //htmly页面高亮显示的格式化，默认是<b></b>即加粗
        Formatter formatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
        Scorer scorer = new QueryScorer(query);
        Highlighter highlighter = new Highlighter(formatter, scorer);

        //设置文字摘要（高亮的部分），此时摘要大小为10
        //int fragmentSize = 10;
        Fragmenter fragmenter = new SimpleFragmenter();
        highlighter.setTextFragmenter(fragmenter);

        /**添加设置文字高亮end*/
        List<Song> songList = new ArrayList<>();
        int endResult = Math.min(scoreDoc.length, start + rows);
        Song song = null;
        for (int i = start; i < endResult; i++) {
            song = new Song();
            int docID = scoreDoc[i].doc;
            //docID lucene的索引库里面有很多的document，lucene为每个document定义了一个编号，唯一标识，自增长
            System.out.println("标识docID=" + docID);
            Document document = indexSearcher.doc(docID);
            /**获取文字高亮的信息begin*/
            System.out.println("==========================");
            TokenStream tokenStream = LuceneUtils.getAnalyzer().tokenStream("name", new StringReader(document.get("name")));
            String name = highlighter.getBestFragment(tokenStream, document.get("name"));
            System.out.println("songName=" + name);
            System.out.println("==========================");

            TokenStream tokenStream1 = LuceneUtils.getAnalyzer().tokenStream("author", new StringReader(document.get("author")));
            String author = highlighter.getBestFragment(tokenStream1, document.get("author"));
            System.out.println("author=" + author);
            System.out.println("==========================");

            TokenStream tokenStream2 = LuceneUtils.getAnalyzer().tokenStream("album", new StringReader(document.get("album")));
            String album = highlighter.getBestFragment(tokenStream2, document.get("album"));
            System.out.println("album=" + album);
            System.out.println("==========================");
            /**获取文字高亮的信息end*/

            song.setId(Integer.parseInt(document.get("id")));
            song.setUrl(document.get("url"));
            if (name != null) {
                song.setName(name);
            } else {
                song.setName(document.get("name"));
            }
            if (author != null) {
                song.setAuthor(author);
            } else {
                song.setAuthor(document.get("author"));
            }
            if (album != null) {
                song.setAlbum(album);
            } else {
                song.setAlbum(document.get("album"));
            }
            songList.add(song);
        }
        return songList;
    }
}
